﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Comm;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Kinlo.Core.Service;
using Kinlo.Model;
using Kinlo.Repo;
using Kinlo.UI.Main.View;

namespace Kinlo.UI.Main.VM
{
    public class MainVM : ViewModelBase
    {
        MainWindow View;
        System.Timers.Timer timer = new System.Timers.Timer(2000);
        //System.Timers.Timer timer2 = new System.Timers.Timer(2000);

        AfterWeightFirstRep AFDB = new AfterWeightFirstRep();
        BeforWeightFirstRep BFDB = new BeforWeightFirstRep();
        CodeFirstRep CFDB = new CodeFirstRep();
        CounterRep CNTDB = new CounterRep();
        CoreService CoreService;
        public MainVM(MainWindow view)
        {
            View = view;
            EventInfos = new ObservableCollection<string>();
            ScanBarcode = new ObservableCollection<CodeFirst>();
            FrontWeights = new ObservableCollection<BeforWeightFirst>();
            AfterWeights = new ObservableCollection<AfterWeightFirst>();
            timer.Elapsed += Timer_Elapsed;
            timer.Enabled = true;
            //timer2.Elapsed += Timer2_Elapsed;
            //timer2.Enabled = true;
            Messenger.Default.Register<CodeFirst>(this, "SendCodeFirst", new Action<CodeFirst>((w) => AddCodeFirst(w)));
            Messenger.Default.Register<CodeFirst>(this, "SendShortCicuteTest", new Action<CodeFirst>((w) => UpdateShortCicuteResult(w)));
            Messenger.Default.Register<BeforWeightFirst>(this, "SendBeforWeightFirst", new Action<BeforWeightFirst>((w) => AddBeforWeightFirst(w)));
            Messenger.Default.Register<AfterWeightFirst>(this, "SendAfterWeightFirst", new Action<AfterWeightFirst>((w) => AddAfterWeightFirst(w)));
            Messenger.Default.Register<ReWork>(this, "SendReWork", new Action<ReWork>((w) => AddReWorkData(w)));
            Messenger.Default.Register<string>(this, "CmdUpdateBatchNo", new Action<string>((i) =>
            {
                BatchNo = GlobalValues.BatchNo;
                BatchNo1 = GlobalValues.BatchNo1;
            }));
            Messenger.Default.Register<string>(this, "CmdUpdateJDBatchNo", new Action<string>((i) =>
            {
                JDBatchNo = GlobalValues.JDBatchNo;
            }));
            Messenger.Default.Register<string>(this, "CmdUpdateItemNo", new Action<string>((i) =>
            {
                ItemBatchNo = "|" + GlobalValues.ItemNo + ":" + GlobalValues.ItemBatchNo + ";" + GlobalValues.ItemNum;
            }));
            Messenger.Default.Register<bool>(this, "SendPLCStatus", new Action<bool>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    PlcStatus = i;
                }));
            }));

            Messenger.Default.Register<bool>(this, "SendDatabaseStatus", new Action<bool>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    DatabaseStatus = i;
                }));
            }));
            Messenger.Default.Register<int>(this, "SendINCount", new Action<int>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    INCount = i;
                }));
            }));
            Messenger.Default.Register<int>(this, "SendOutCount", new Action<int>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    OutCount = i;
                }));
            }));
            Messenger.Default.Register<int>(this, "SendOKCount", new Action<int>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    OKCount = i;
                }));
            }));
            Messenger.Default.Register<int>(this, "SendNGCount", new Action<int>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    NGCount = i;
                }));
            }));
            Messenger.Default.Register<string>(this, "ChangeTitle", new Action<string>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UpdateTitle();
                }));
            }));
            Messenger.Default.Register<string>(this, "UpdateUIGloableValues", new Action<string>((i) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UpdateUIGloableValues();
                }));
            }));

            RaisePropertyChanged(() => QualifiRate);
            Messenger.Default.Register<string>(this, "ReceiveEventInfo", new Action<string>((s) =>
            {
                this.View.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (EventInfos.Count > 5000)
                        EventInfos.Clear();
                    var msg = DateTime.Now.ToString("HH:mm:ss") + " " + s;
                    EventInfos.Add(msg);
                    this.View.lstEvent.ScrollIntoView(msg);
                    RaisePropertyChanged(() => EventInfos);
                }));
            }));
            var addr = ConfigurationManager.AppSettings["Ipaddr"];
            PlcAddr = addr;
            Task.Run(() =>
            {
                Thread.Sleep(1000);
                CoreService.Loaded += CoreService_Loaded;
                CoreService = new CoreService();
            });
        }

        private void CoreService_Loaded(object sender, object e)
        {
            UpdateUIGloableValues();
        }

        void UpdateUIGloableValues()
        {
            try
            {
                BatchNo = GlobalValues.BatchNo;
                BatchNo1 = GlobalValues.BatchNo1;
                JDBatchNo = GlobalValues.JDBatchNo;
                EquNo = GlobalValues.EquNo;
                EmpNo = GlobalValues.EmpNo;
                MoNumber = GlobalValues.MoNumber;
                GroupCode = GlobalValues.GroupCode;
                GroupName = GlobalValues.GroupName;
            }
            catch (Exception ex)
            {
                Logger.Info(string.Format("更新界面发生异常{0}", ex.Message));
            }
        }
        void AddCodeFirst(CodeFirst w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() =>
            {
                ScanBarcode.Add(w);
                this.View.datagridview1.ScrollIntoView(w);
            }));
        }
        void UpdateShortCicuteResult(CodeFirst w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() =>
            {
                var first = ScanBarcode.Where(s => s.Code == w.Code).FirstOrDefault();
                if (first != null)
                {
                    first.ShortResult = w.ShortResult;
                    first.ShortResult2 = w.ShortResult2;
                    first.ShortUnit = w.ShortUnit;
                    first.ShortUnitSeq = w.ShortUnitSeq;
                    first.ShortValue = w.ShortValue;
                    first.ProductDate = w.ProductDate;
                    first.ShortVoltage = w.ShortVoltage;
                    first.ShortDuration = w.ShortDuration;
                    first.Drop1 = w.Drop1;
                    first.Drop1Result = w.Drop1Result;
                    first.Drop2 = w.Drop2;
                    first.Drop2Result = w.Drop2Result;
                    first.VoltageResult1 = w.VoltageResult1;
                    first.VoltageResult2 = w.VoltageResult2;
                    first.VPResult = w.VPResult;
                    first.UpperTime = w.UpperTime;
                    first.TH_Result = w.TH_Result;
                    first.TL_Result = w.TL_Result;
                    first.OpenResult = w.OpenResult;
                    first.Resistance = w.Resistance;
                    first.ResistanceResult = w.ResistanceResult;
                    first.Voltage = w.Voltage;
                    first.Result = w.Result;
                    first.Drop3 = w.Drop3;
                    first.Drop3Result = w.Drop3Result;
                    first.ResidueVoltage = w.ResidueVoltage;
                    first.ResidueVoltageResult = w.ResidueVoltageResult;
                    first.VP = w.VP;
                    first.TK = w.TK;
                    first.TF = w.TF;
                    first.VD1 = w.VD1;
                    first.VD2 = w.VD2;
                    first.VD3 = w.VD3;
                    first.R = w.R;
                    first.RT = w.RT; 
                }
                else
                {
                    ScanBarcode.Add(w);
                }
                //this.View.datagridview1.ScrollIntoView(w);
            }));
        }
        void AddBeforWeightFirst(BeforWeightFirst w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() =>
            {
                FrontWeights.Add(w);
                this.View.datagridview2.ScrollIntoView(w);
            }));
        }
        void AddAfterWeightFirst(AfterWeightFirst w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() =>
            {
                AfterWeights.Add(w);
                this.View.datagridview3.ScrollIntoView(w);
            }));
        }

        void AddReWorkData(ReWork w)
        {
            this.View.Dispatcher.BeginInvoke(new Action(() =>
            {
                try
                {
                    ReWorkDatas.Add(w);
                    this.View.datagridview4.ScrollIntoView(w);
                }
                catch (Exception ex)
                {
                    Logger.Info($"AddReWorkData {ex}");
                }
            }));
        }


        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

        }

        string plcAddr;
        /// <summary>
        /// PLC地址
        /// </summary>ww
        public string PlcAddr
        {
            get { return plcAddr; }
            set
            {
                plcAddr = value;
                RaisePropertyChanged(() => PlcAddr);
            }
        }
        string title;
        /// <summary>
        /// Title
        /// </summary>ww
        public string Title
        {
            get { return title; }
            set
            {
                title = value;
                RaisePropertyChanged(() => Title);
            }
        }
        bool plcStatus;
        /// <summary>
        /// PLC状态
        /// </summary>
        public bool PlcStatus
        {
            get { return plcStatus; }
            set
            {
                plcStatus = value;
                RaisePropertyChanged(() => PlcStatus);
            }
        }
        bool databaseStatus;
        /// <summary>
        /// 数据库状态
        /// </summary>
        public bool DatabaseStatus
        {
            get { return databaseStatus; }
            set
            {
                databaseStatus = value;
                RaisePropertyChanged(() => DatabaseStatus);
            }
        }

        string equNo;
        /// <summary>
        ///设备号
        /// </summary>
        public string EquNo
        {
            get { return equNo; }
            set
            {
                equNo = value;
                RaisePropertyChanged(() => EquNo);
            }
        }
        string batchNo;
        /// <summary>
        ///电解液料号
        /// </summary>
        public string BatchNo
        {
            get { return batchNo; }
            set
            {
                batchNo = value;
                RaisePropertyChanged(() => BatchNo);
            }
        }
        string batchNo1;
        /// <summary>
        ///电解液批次号
        /// </summary>
        public string BatchNo1
        {
            get { return batchNo1; }
            set
            {
                batchNo1 = value;
                RaisePropertyChanged(() => BatchNo1);
            }
        }



        string jdBatchNo;
        /// <summary>
        ///胶钉批次号
        /// </summary>
        public string JDBatchNo
        {
            get { return jdBatchNo; }
            set
            {
                jdBatchNo = value;
                RaisePropertyChanged(() => JDBatchNo);
            }
        }
        string itemBatchNo;
        /// <summary>
        ///物料信息
        /// </summary>
        public string ItemBatchNo
        {
            get { return itemBatchNo; }
            set
            {
                itemBatchNo = value;
                RaisePropertyChanged(() => ItemBatchNo);
            }
        }
        //MoNumber}
        //GroupCode
        //GroupName

        string moNumber;
        /// <summary>
        /// 制令单
        /// </summary>
        public string MoNumber
        {
            get { return moNumber; }
            set
            {
                moNumber = value;
                RaisePropertyChanged(() => MoNumber);
            }
        }
        string groupCode;
        /// <summary>
        /// 工序代码
        /// </summary>
        public string GroupCode
        {
            get { return groupCode; }
            set
            {
                groupCode = value;
                RaisePropertyChanged(() => GroupCode);
            }
        }
        string groupName;
        /// <summary>
        /// 组别
        /// </summary>
        public string GroupName
        {
            get { return groupName; }
            set
            {
                groupName = value;
                RaisePropertyChanged(() => GroupName);
            }
        }

        string empNo;
        /// <summary>
        /// 操作人
        /// </summary>
        public string EmpNo
        {
            get { return empNo; }
            set
            {
                empNo = value;
                RaisePropertyChanged(() => EmpNo);
            }
        }

        int inCount;
        /// <summary>
        /// 投入
        /// </summary>
        public int INCount
        {
            get { return inCount; }
            set
            {
                inCount = value;

                RaisePropertyChanged(() => INCount);
            }
        }
        int outCount;
        /// <summary>
        /// 产出
        /// </summary>
        public int OutCount
        {
            get { return outCount; }
            set
            {
                outCount = value;
                RaisePropertyChanged(() => OutCount);
            }
        }
        int okCount;
        /// <summary>
        /// 合格数
        /// </summary>
        public int OKCount
        {
            get { return okCount; }
            set
            {
                okCount = value;
                RaisePropertyChanged(() => OKCount);
                RaisePropertyChanged(() => QualifiRate);
            }
        }
        int ngCount;
        /// <summary>
        /// 不合格数
        /// </summary>
        public int NGCount
        {
            get { return ngCount; }
            set
            {
                ngCount = value;
                RaisePropertyChanged(() => NGCount);
                RaisePropertyChanged(() => QualifiRate);
            }
        }
        string qualifiRate;
        /// <summary>
        /// 合格率
        /// </summary>
        public string QualifiRate
        {
            get
            {
                var r = ((OKCount + NGCount) <= 0) ? (OKCount / (OKCount + NGCount + 0.00001)).ToString("P2") : (OKCount / (OKCount + NGCount + 0.0)).ToString("P2");
                return r;
            }
            set
            {
                RaisePropertyChanged(() => QualifiRate);
            }
        }

        ObservableCollection<string> eventInfos;
        /// <summary>
        /// 日志信息
        /// </summary>
        public ObservableCollection<string> EventInfos
        {
            get { return eventInfos; }
            set
            {
                eventInfos = value;
                RaisePropertyChanged(() => EventInfos);
            }
        }
        ObservableCollection<CodeFirst> scanBarcode;
        /// <summary>
        /// 前扫码
        /// </summary>
        public ObservableCollection<CodeFirst> ScanBarcode
        {
            get { return scanBarcode; }
            set
            {
                scanBarcode = value;
                RaisePropertyChanged(() => ScanBarcode);
            }
        }
        ObservableCollection<BeforWeightFirst> frontWeights;
        /// <summary>
        /// 前称重
        /// </summary>
        public ObservableCollection<BeforWeightFirst> FrontWeights
        {
            get { return frontWeights; }
            set
            {
                frontWeights = value;
                RaisePropertyChanged(() => FrontWeights);
            }
        }
        ObservableCollection<AfterWeightFirst> afterWeights;
        /// <summary>
        /// 后称重
        /// </summary>
        public ObservableCollection<AfterWeightFirst> AfterWeights
        {
            get { return afterWeights; }
            set
            {
                afterWeights = value;
                RaisePropertyChanged(() => AfterWeights);
            }
        }
        ObservableCollection<ReWork> reWorkDatas = new ObservableCollection<ReWork>();
        /// <summary>
        /// 返工
        /// </summary>
        public ObservableCollection<ReWork> ReWorkDatas
        {
            get { return reWorkDatas; }
            set
            {
                reWorkDatas = value;
                RaisePropertyChanged(() => ReWorkDatas);
            }
        }


        RelayCommand cmdConnectPlc;
        /// <summary>
        /// 连接PLC
        /// </summary>
        public RelayCommand CmdConnectPlc
        {
            get { return cmdConnectPlc ?? (cmdConnectPlc = new RelayCommand(() => DoCmdConnectPlc())); }
        }
        void DoCmdConnectPlc()
        {
            try
            {
                if (GlobalValues.MesOnOff)
                {
                    if (new CheckUserDoView().ShowDialog() == true)
                    {
                        Logger.Info("start");
                        CoreService.Start();
                    }
                    else
                    {
                        Logger.Info("cancel");
                    }
                }
                else
                {
                    Logger.Info("start");
                    CoreService.Start();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "检验失败");
            }
        }

        RelayCommand cmdQuery;
        /// <summary>
        /// 查询
        /// </summary>
        public RelayCommand CmdQuery
        {
            get { return cmdQuery ?? (cmdQuery = new RelayCommand(() => DoCmdQuery())); }
        }
        void DoCmdQuery()
        {
            var win = new QueryView();
            win.ShowDialog();
        }
        RelayCommand cmdBatchInput;
        /// <summary>
        /// 电解液批次录入
        /// </summary>
        public RelayCommand CmdBatchInput
        {
            get { return cmdBatchInput ?? (cmdBatchInput = new RelayCommand(() => DoCmdBatchInput())); }
        }
        void DoCmdBatchInput()
        {
            var win = new BatchInputView();
            win.ShowDialog();
        }


        RelayCommand cmdDJYSetting;
        /// <summary>
        /// 电解液设置
        /// </summary>
        public RelayCommand CmdDJYSetting
        {
            get { return cmdDJYSetting ?? (cmdDJYSetting = new RelayCommand(() => DoCmdDJYSetting())); }
        }
        void DoCmdDJYSetting()
        {
            var win = new DJYSetttingView();
            win.ShowDialog();
        }

        RelayCommand cmdItemSetting;
        /// <summary>
        /// 物料信息
        /// </summary>
        public RelayCommand CmdItemSetting
        {
            get { return cmdItemSetting ?? (cmdItemSetting = new RelayCommand(() => DoCmdItemSetting())); }
        }
        void DoCmdItemSetting()
        {
            var win = new ItemSettingView();
            win.ShowDialog();
        }






        RelayCommand cmdJDBatchInput;
        /// <summary>
        /// 胶钉批次录入
        /// </summary>
        public RelayCommand CmdJDBatchInput
        {
            get { return cmdJDBatchInput ?? (cmdJDBatchInput = new RelayCommand(() => DoCmdJDBatchInput())); }
        }
        void DoCmdJDBatchInput()
        {
            var win = new JDBatchInputView();
            win.ShowDialog();
        }

        RelayCommand cmdRepairInput;
        /// <summary>
        /// 手工补液
        /// </summary>
        public RelayCommand CmdRepairInput
        {
            get { return cmdRepairInput ?? (cmdRepairInput = new RelayCommand(() => DoCmdRepairInput())); }
        }
        void DoCmdRepairInput()
        {
            if (GlobalValues.OpType != "EC" && GlobalValues.Locate != "ZH")
            {
                var win = new RepairInputView();
                win.ShowDialog();
            }
            else
            {
                MessageBox.Show("该注液站无补液功能", "错误");
            }
        }

        RelayCommand cmdMoNumber;
        public RelayCommand CmdMoNumber
        {
            get { return cmdMoNumber ?? (cmdMoNumber = new RelayCommand(() => DoCmdCmdMoNumber())); }
        }
        void DoCmdCmdMoNumber()
        {
            var win1 = new MoNumberView();
            win1.ShowDialog();
        }

        RelayCommand cmdGroupName;
        public RelayCommand CmdGroupName
        {
            get { return cmdGroupName ?? (cmdGroupName = new RelayCommand(() => DoCmdGroupName())); }
        }
        void DoCmdGroupName()
        {
            var win1 = new GroupNameView();
            win1.ShowDialog();
        }

        RelayCommand cmdSetting;
        /// <summary>
        /// 参数设置
        /// </summary>
        public RelayCommand CmdSetting
        {
            get { return cmdSetting ?? (cmdSetting = new RelayCommand(() => DoCmdSetting())); }
        }
        void DoCmdSetting()
        {
            var win = new PassConfirmView();
            if (win.ShowDialog() == true)
            {
                var win1 = new MesSettingView();
                win1.ShowDialog();
            }
        }

        RelayCommand cmdCounterClear;
        /// <summary>
        /// 计算清零
        /// </summary>
        public RelayCommand CmdCounterClear
        {
            get { return cmdCounterClear ?? (cmdCounterClear = new RelayCommand(() => DoCmdCounterClear())); }
        }
        void DoCmdCounterClear()
        {
            try
            {
                if (MessageBox.Show("确认要清零计算器", "提示", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                {
                    var result = CNTDB.ClearCounter();
                    if (result > 0)
                    {
                        INCount = 0;
                        OutCount = 0;
                        OKCount = 0;
                        NGCount = 0;
                        Interlocked.Exchange(ref CoreService.InCount, 0);
                        Interlocked.Exchange(ref CoreService.OutCount, 0);
                        Interlocked.Exchange(ref CoreService.OKCount, 0);
                        Interlocked.Exchange(ref CoreService.NGCount, 0);
                    }
                    else
                    {
                        MessageBox.Show("计数清零失败", "错误");
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        RelayCommand<DataGridRowEventArgs> cmdLoadingRow;
        public RelayCommand<DataGridRowEventArgs> CmdLoadingRow
        {
            get { return cmdLoadingRow ?? (cmdLoadingRow = new RelayCommand<DataGridRowEventArgs>((e) => DoCmdLoadingRow(e))); }
        }
        void DoCmdLoadingRow(DataGridRowEventArgs e)
        {
            e.Row.Header = e.Row.GetIndex() + 1;
        }
        void UpdateTitle()
        {
            if (GlobalValues.OpType.ToUpper() == "YC")
            {
                this.Title = string.Format("精朗称重软件\t\t【{0}】", "一次注液");
            }
            else if (GlobalValues.OpType.ToUpper() == "EC")
            {
                var val = GlobalValues.EnableVarInj ? " 【变量注液】" : "";
                this.Title = string.Format("精朗称重软件\t\t【{0}】{1}", "二次注液", val);
            }
            else if (GlobalValues.OpType.ToUpper() == "SC")
            {
                var val = GlobalValues.EnableVarInj ? " 【变量注液】" : "";
                this.Title = string.Format("精朗称重软件\t\t【{0}】{1}", "三次注液", val);
            }
            GroupCode = GlobalValues.GroupCode;
        }

    }
}
